home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / lisp / glisp / glisp.000 / GLISP.UNIX.TAR / closunix / closstr2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-03  |  5.7 KB  |  290 lines

  1. /*                 GRAPHIC LISP            */
  2. /*        Scritto nel 1991-94 da Zoia Andrea Michele     */
  3. /*        Via Pergola #1 Tirano (SO) Tel. 0342-704210    */
  4. /* file closstr2.c */
  5.  
  6. #include "clos.h"
  7.  
  8. /* MEMORIA-STRINGHE
  9.  
  10.      namebuf                                  namepunt (nameidx)
  11.        |                                          |
  12.        nnnnnnnnssssss ... ss0nnnnnnnnsssss ... ss00000000000000000 ...
  13.      |        |         |                      |
  14.      |      Stringa    Zero finale            Primo byte libero
  15.      |
  16.        puntatore del nodo di appartenenza
  17.  
  18. nameidx Φ il numero di bytes allocati
  19. maxname Φ il numero dell' ultimo byte (max 65535)
  20. */
  21.  
  22. /* NB: non si deve MAI passare NULL ad una funzione */
  23.  
  24.  
  25. #define CHAR_GARBAGE    ((char)-1)
  26. #define SH(x)        ((str_t)(x))
  27. #define SP(x)        ((char *)(x))
  28.  
  29. char  *namebuf=NULL;
  30. char  *namepunt;
  31. unsigned long int  nameidx;
  32. unsigned long int  maxname;
  33.  
  34. #ifdef LISPMEM_DEBUG
  35.  int look_namebuf();
  36. #endif
  37.  
  38.  
  39.  
  40. str_t    string_put(s,h)
  41. char    *s;
  42. node    h;
  43. {
  44.  /* alloca la stringa s associata al nodo n                 */
  45.  /* ritorna l'handler della stringa allocata                 */
  46.  /* insieme alla stringa si mette anche il nodo a cui appartiene:       */
  47.  /* questo per il garbage collection                    */
  48.  
  49.  char         *tmp;
  50.  unsigned int i;
  51.  unsigned int len_s;
  52.  int          len_n;
  53.  
  54.  if(string_isallocable(s))
  55.     error(E_NOMEMSTRINGS,ERR_TCRIT|ERR_MERROR|ERR_PVOID,NULL);
  56.  
  57.  
  58.  len_s=(unsigned int)strlen(s)+1;/* lunghezza della stringa */
  59.  len_n=(int)sizeof(node);    /* lunghezza del puntatore */
  60.  
  61.  
  62.  *(node *)namepunt=h;        /* mette l'handler del nodo prima della stringa */
  63.                 /* NOTA: ovunque si suppone che node sia un tipo di dato
  64.                     direttamente maneggiabile dall' op '='
  65.                     (int)(unsigned)(long)ecc... cioe' un tipo semplice */
  66.  for(i=0;i<len_n;i++){        /* incrementa il puntatore ed il contatore */
  67.     namepunt++;
  68.     nameidx++;
  69.  }
  70.  tmp=namepunt;            /* salva il puntatore alla stringa */
  71.  strcpy(namepunt,s);        /* mette in memoria la stringa */
  72.  for(i=0;i<len_s;i++){        /* incrementa il puntatore ed il contatore */
  73.     namepunt++;
  74.     nameidx++;
  75.  }
  76.  return SH(tmp);
  77. }
  78.  
  79. char *string_get(s,b)
  80. str_t s;
  81. char  *b;
  82. {
  83.  /* preleva la stringa s e la mette nel buffer b */
  84.  return strcpy((char*)b,SP(s));
  85. }
  86.  
  87. int string_del(st)
  88. str_t st;
  89. {
  90.  /* cancella la stringa st e rende il suo spazio disponibile al gc */
  91.  int  i;
  92.  char *s;
  93.  
  94.  s=SP(st);
  95.  if(s==NULL)
  96.    error(E_CLOSSTR2ERR,ERR_TCRIT|ERR_MINTERNAL|ERR_PSTRING,"FROM:string_del");
  97.  for(i=0;i<sizeof(node);i++){
  98.    s--;
  99.  }                /* s punta al puntatore del nodo */
  100.  *(node *)s=VOID;        /* mette l'handler del nodo speciale VOID */
  101.                 /* prima della stringa in modo da segnalare */
  102.                 /* che questa Φ cancellata */
  103.  return OK;
  104. }
  105.  
  106.  
  107. int     string_gc()
  108. {
  109.  /* compatta lo spazio delle stringhe togliendo quelle il cui nodo Φ = VOID */
  110.  unsigned int i;
  111.  unsigned long newnidx,nidx;
  112.  char *nptr,*newnptr;
  113.  node n;
  114.  
  115.  newnidx=0L;
  116.  nidx   =0L;
  117.  nptr   =namebuf;
  118.  newnptr=namebuf;
  119.  
  120.  
  121.  
  122.  
  123.  while(nidx<nameidx){
  124.    if( *(node*)nptr==VOID ){    /* salta questa stringa cancellata */
  125.      for(i=0;i<sizeof(node);i++){/* salta il puntatore del nodo */
  126.        nidx++;
  127.        nptr++;
  128.      }
  129.      while(nidx++,*nptr++);     /* salta la stringa */
  130.    }else{            /* recupera la stringa */
  131.      n=*(node*)newnptr=*(node*)nptr; /* copia il puntatore del nodo */
  132.      for(i=0;i<sizeof(node);i++){/* salta il puntatore del nodo */
  133.        nidx++;
  134.        nptr++;
  135.        newnidx++;
  136.        newnptr++;
  137.      }
  138.      switch(GET_NTYPE(n)){    /* modifica il puntatore del nodo */
  139.        case NT_IS_NAME:
  140.      if(SP(NAME(n))==nptr){
  141.        NAME(n)=SH(newnptr);
  142.      }else
  143.        error(E_GCS1,ERR_MINTERNAL|ERR_TNORM|ERR_PSTRING,nptr);
  144.      break;
  145.        case NT_IS_VALUE:
  146.      if(SP(STRING(n))==nptr){
  147.        STRING(n)=SH(newnptr);
  148.      }else
  149.        error(E_GCS2,ERR_MINTERNAL|ERR_TNORM|ERR_PSTRING,nptr);
  150.      break;
  151.        default:
  152.      error(E_GCS3,ERR_MINTERNAL|ERR_TNORM|ERR_PSTRING,nptr);
  153.      }
  154.      /* copia e salta la stringa */
  155.      while(*newnptr=*nptr, newnidx++, newnptr++, nidx++, *nptr++);
  156.    }
  157.  }
  158.  if(namepunt!=nptr)
  159.    error(E_CLOSSTR2ERR,ERR_TNORM|ERR_MINTERNAL|ERR_PSTRING,"FROM:string_gc namepunt!=nptr");
  160.  namepunt=newnptr;
  161.  nameidx =newnidx;
  162.  
  163. #ifdef LISPMEM_DEBUG
  164.   look_namebuf();
  165. #endif
  166.  return OK;
  167. }
  168.  
  169. int string_isallocable(s)
  170. char *s;
  171. {
  172.  if(nameidx+(unsigned long int)strlen(s)+(unsigned long int)sizeof(node)+1L>maxname){
  173.    string_gc();
  174.    if(nameidx+(unsigned long int)strlen(s)+(unsigned long int)sizeof(node)+1L>maxname){
  175.       node_gc();
  176.       string_gc();
  177.       if(nameidx+(unsigned long int)strlen(s)+(unsigned long int)sizeof(node)+1L>maxname){
  178.     return ERROR;
  179.       }
  180.    }
  181.  }
  182.  return OK;
  183. }
  184.  
  185. int string_free()
  186. {
  187.  if(namebuf)
  188.    free(namebuf);
  189.  namebuf=NULL;
  190.  return OK;
  191. }
  192.  
  193. int string_malloc(s)
  194. lsiz_t s;
  195. {
  196.  char  *tmp;
  197.  if(s>0xffffL)return ERROR;
  198.  if((tmp=(char  *)malloc((unsigned)s))==NULL){
  199.    namebuf=namepunt=NULL;
  200.    nameidx=maxname=0L;
  201.    return ERROR;
  202.  }
  203.  namebuf=namepunt=tmp;
  204.  nameidx=0L;
  205.  maxname=s;
  206.  return OK;
  207. }
  208.  
  209.  
  210. char    *string_getconv(s_i,s_o)
  211. str_t    s_i;
  212. char    *s_o;
  213. {
  214.  char     *p=SP(s_i);
  215.  char     *buf=s_o;
  216.  
  217.  while(*p){
  218.     if(*p=='\\'){
  219.         switch(*++p){
  220.  
  221.             case '"':
  222.             case '\\':
  223.                 *buf++=*p;
  224.                 break;
  225.  
  226.             case 'a':
  227.                 *buf++='\a';
  228.                 break;
  229.             case 'b':
  230.                 *buf++='\b';
  231.                 break;
  232.             case 'f':
  233.                 *buf++='\f';
  234.                 break;
  235.             case 'n':
  236.                 *buf++='\n';
  237.                 break;
  238.             case 't':
  239.                 *buf++='\t';
  240.                 break;
  241.             case 'v':
  242.                 *buf++='\v';
  243.                 break;
  244.             case  0 :
  245.                 *buf++='\\';
  246.                 *buf=0;
  247.                 return s_o;
  248.             default:
  249.                 *buf++='\\';
  250.                 *buf++=*p;
  251.         }
  252.     }
  253.     else
  254.         *buf++=*p;
  255.  
  256.     p++;
  257.  }
  258.  *buf=0;
  259.  return s_o;
  260. }
  261.  
  262.  
  263.  
  264.  
  265.  
  266. #ifdef LISPMEM_DEBUG
  267. int look_namebuf()
  268. {
  269.  /* e' una vecchia versione ... modificare !!! */
  270.  char  *p;
  271.  int i;
  272.  
  273.  p=namebuf;
  274.  
  275.  while(p<namepunt){
  276.     if(*p==CHAR_GARBAGE){
  277.         printf("GARBAGE\n");
  278.         p++;
  279.     }
  280.     else{
  281.     printf("%s",p);
  282.     while(*p++);
  283.     printf(" node %p\n",*(node *)p);
  284.     for(i=0;i<sizeof(node);i++)
  285.         p++;
  286.     }
  287.  }
  288. }
  289. #endif
  290.